31. Spring3 - 集合属性赋值,FactoryBean

集合属性赋值

在给属性起名的时候,不能使用小写字母后面立即跟大写的形式(bossMap 这种是可以的),例如 sList 因为这样生成的 set 方法名称是 setsList , 在 xml property 中为该属性赋值的时候,会找不到 sList 的 set 方法,因为期待的正确的 set 方法是 setSList, 而生成的是 setsList

为 list, set, array 赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!-- 为 List 集合赋值 -->
<bean id="t1" class="com.itguigu.spring.di.Teacher">
<property name="tname" value="长老师"></property>
<property name="tage" value="23"></property>
<property name="cls">
<list>
<value>A</value>
<value>B</value>
<value>C</value>
</list>
</property>
</bean>

<!-- 为 List 集合赋值 -->
<bean id="t2" class="com.itguigu.spring.di.Teacher">
<property name="tname" value="长老师"></property>
<property name="tage" value="23"></property>
<property name="students">
<list>
<ref bean="s1"/>
<ref bean="s2"/>
<ref bean="s3"/>
</list>
</property>
</bean>

数组的定义和List一样,都使用 <list> 元素 (数组也可以使用 <array> 标签)。Set需要使用 <set> 标签,定义的方法与List一样。

为 map 赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- 为 Map 集合赋值 -->
<bean id="t3" class="com.itguigu.spring.di.Teacher">
<property name="tname" value="五老师"></property>
<property name="tage" value="45"></property>
<property name="bossMap">
<map>
<entry>
<key>
<value>10001</value>
</key>
<value>王校长</value>
</entry>
<entry>
<key>
<value>10002</value>
</key>
<value>李局长</value>
</entry>
</map>
</property>
</bean>

集合类型的 bean

在上面我们为 list 赋值的例子中,我们为 cls 和 students 两个 list 都赋了值。在 spring 中我们还可以专门创建一种集合类型的 bean,这样赋值会更方便,这个集合也可以供其他 bean 使用。

使用前需先加入标签 xmlns:util=*"http://www.springframework.org/schema/util"*

1
2
3
4
5
6
7
8
9
10
11
12
13
<bean id="t4" class="com.itguigu.spring.di.Teacher">
<property name="tname" value="美老师"></property>
<property name="tage" value="28"></property>
<!-- 直接应用创建好的集合类型的 bean -->
<property name="students" ref="students"></property>
</bean>

<!-- 集合类型的bean -->
<util:list id="students">
<ref bean="s4"/>
<ref bean="s5"/>
<ref bean="s5"/>
</util:list>

同理,我们也可以使用 <util:map> <util:set> 标签创建对应的集合。可参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!-- map -->
<util:map id="map">
<entry>
<key>
<value>1</value>
</key>
<value>张三</value>
</entry>
<entry>
<key>
<value>2</value>
</key>
<value>李四</value>
</entry>
</util:map>

<!-- set -->
<util:set id="set">
<value>张三</value>
<value>王五</value>
<value>赵六</value>
</util:set>

FactoryBean

Spring 中有两种类型的 bean,一种是普通 bean,另一种是工厂 bean,即 FactoryBean。工厂bean跟普通 bean 不同,其返回的对象不是指定类的一个实例,其返回的是该工厂 bean 的 getObject 方法所返回的对象。

例如,我们创建一个类 Car

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.itguigu.spring.factorybean;

public class Car {
private String brand;
private Double price;

public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
@Override
public String toString() {
return "Car [brand=" + brand + ", price=" + price + "]";
}
}

在创建一个类 myFactory 让其实现 FactoryBean 接口,使其成为一个工厂 baen。工厂 baen 需要复写三个方法,getObject 会将创建好的 bean 返回给 IOC 容器,getObjectType 返回是 bean 的类型,isSingleton 表示创建的 bean 是否是单例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.itguigu.spring.factorybean;

import org.springframework.beans.factory.FactoryBean;

public class myFactory implements FactoryBean<Car>{

@Override
public Car getObject() throws Exception {
Car car = new Car();
car.setBrand("奥迪");
car.setPrice(99999.0);
return car;
}

@Override
public Class<?> getObjectType() {
return Car.class;
}

@Override
public boolean isSingleton() {
return false;
}
}

在 factory-bean.xml 中加入创建的 myFactory 类。

1
2
3
4
5
6
7
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="factory" class="com.itguigu.spring.factorybean.myFactory"></bean>
</beans>

最后进行测试,结果会发现,我们在 xml 中虽然配置的是 myFactory 类,但是获取到的确实 Car 对象。这就是工厂 bean 的作用,即工厂 bean 跟普通 bean 不同,其返回的对象不是指定类的一个实例,其返回的是该工厂 bean 的 getObject 方法所返回的对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.itguigu.spring.factorybean;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
public static void main(String[] args) {
ApplicationContext axApplicationContext = new ClassPathXmlApplicationContext("factory-bean.xml");
Object bean = axApplicationContext.getBean("factory");
System.out.println(bean);
// Car [brand=奥迪, price=99999.0]
}
}

代码地址